﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
namespace Library.Gsm.Wavecom {
	public class WavecomGsm : BaseGsm {
		public WavecomGsm() {
			ConnectionType = ConnectionType.Serial;
		}

		protected override Sms ParseReadMsgResp(StringCollection response) {
			return ParseReadMsgRespTextModeDeliver(response);
		}
		private List<Sms> ParseListMsgRespTextModeDeliver(StringCollection response) {
			const string cmdKey = "+CMGL:";

			var result = new List<Sms>();
			Sms lastSms = null;

			for (int index = 0; index < response.Count; index++) {
				var line = response[index];
				if (line.StartsWith(cmdKey)) {
					var infos = ParseHeader(line, cmdKey.Length);
					if (infos.Length < 3) throw new ResponseFormatException("Reponse List Msg from text mode delivery: " + line);
					var headerSms = new Sms {
						Status = ConvertSmsStatus(infos[1].Trim().ToUpper()),
						SendOrReceiveNumber = infos[2].Trim()
					};
					lastSms = headerSms;
					try {
						headerSms.Index = Int32.Parse(infos[0].Trim());
					} catch {
						throw new ResponseFormatException("Parse Index from list msg in text mode delivery error: Index = " +
																							infos[0].Trim());
					}
					if (infos.Length == 4) {
						headerSms.SendOrReceiveName = infos[3].Trim();
					} else {
						string dateStr;

						if (infos.Length == 6) {
							dateStr = infos[3].Trim();
						} else {
							headerSms.SendOrReceiveName = infos[3].Trim();
							dateStr = infos[4].Trim();
						}
						try {
							dateStr = dateStr.Substring(0, dateStr.Length - 3);
							headerSms.SentOrReceivedDate = ParseDate(dateStr);
						} catch (Exception) {
							headerSms.SentOrReceivedDate = DateTime.Now;
						}
					}


					result.Add(headerSms);
				} else {
					if (lastSms != null) {
						lastSms.Message += line;
					}
				}
			}

			return result;
		}

		private Sms ParseReadMsgRespTextModeDeliver(StringCollection response) {
			const string cmdKey = "+CMGR:";
			//const string dateFormat = "yy/MM/dd,hh:mm:sszzz";

			foreach (var line in response) {
				var sms = new Sms();
				var isDataLine = false;
				while (line != null) {
					if (isDataLine) {
						sms.Message = line;
					} else if (line.StartsWith(cmdKey)) {
						isDataLine = true;
						var infos = ParseHeader(line, cmdKey.Length - 1);
						if (infos.Length < 2)
							throw new ResponseFormatException("Reponse Read Msg from text mode delivery: " + line);
						sms.Status = ConvertSmsStatus(infos[0].ToUpper());
						sms.SendOrReceiveNumber = infos[1].Trim();
						string dateStr;
						if (infos.Length == 3) //<status>,<oa>,<scts>
            {
							dateStr = infos[2].Trim();

						} else if (infos.Length == 4) {
							//<status>,<oa>,<alpha>,<scts>
							sms.SendOrReceiveName = infos[2].Trim();
							dateStr = infos[3].Trim();
						} else {
							//<status>,<oa>,<scts>,<>....
							dateStr = infos[2].Trim();
						}
						try {
							sms.SentOrReceivedDate = ParseDate(dateStr);
						} catch (Exception) {
							sms.SentOrReceivedDate = DateTime.Now;
						}
					}
				}

				return sms;
			}
			return null;
		}

		protected override List<Sms> ParseListMsgResp(StringCollection response) {
			return ParseListMsgRespTextModeDeliver(response);
		}
		protected virtual DateTime ParseDate(string dateStr) {
			var times = new Int32[7];
			//0: YY
			//1: MM
			//2: DD
			//3: HH
			//4: mm
			//5: ss
			//6: time zone

			int timeIndex = 0;
			string timeElement = String.Empty;
			char lastChar = '\0';
			//const string dateFormat = "yy/MM/dd,hh:mm:ss(+/-)zz"; zz is quarter of an hour
			for (int i = 0; i < dateStr.Length; i++) {
				var c = dateStr[i];
				if (Char.IsNumber(c)) {
					timeElement = timeElement + c;
				} else {
					lastChar = c;
					int value;
					if (!Int32.TryParse(timeElement, out value)) {
						value = 0;
					}
					times[timeIndex] = value;
					timeIndex++;
					timeElement = String.Empty;
				}
			}
			if (timeElement.Length > 0) {
				int value;
				if (!Int32.TryParse(timeElement, out value)) {
					value = 0;
				}
				times[timeIndex] = value;
			}

			var date = new DateTime(DateTime.Today.Year - DateTime.Today.Year % 100 + times[0], times[1], times[2], times[3], times[4], times[5]);
			int hourZone;
			if (lastChar == '-') {
				hourZone = times[6];
			} else {
				hourZone = -times[6];
			}
			//var uctDate = date.AddHours(hourZone / (float)4);
			//date = TimeZone.CurrentTimeZone.ToLocalTime(uctDate);
			return date;
		}




		protected override IGsmConnection CreateConnect() {
			switch (ConnectionType) {
				case ConnectionType.Serial:
					return new WaveSerialConnection();
			}

			throw new NotSupportedException("ConnectionType");
		}
	}
}
